package tmt.usercenter.web.controller.app;

import com.tmt.helper.DesHelper;
import com.tmt.spring.validation.RegisterValidateHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.WebAsyncTask;
import springfox.documentation.annotations.ApiIgnore;
import tmt.usercenter.web.controller.RegisterController;
import tmt.usercenter.web.controller.app.bean.*;
import tmt.usercenter.web.domain.ClientSystem;
import tmt.usercenter.web.domain.TmtUser;
import tmt.usercenter.web.domain.security.UserDetailsImpl;
import tmt.usercenter.web.vo.HttpResult;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.Callable;

@Api(tags = "提供用户信息管理所需的接口集合", description = "需要授权才能访问")
@RestController("app-user-controller")
@RequestMapping("/api/user")
@PreAuthorize("#oauth2.hasScope('uc_api_info')")
public class UserController extends AppBaseController {

    //此常量的值不可更改
    private static final String INTRODUCER_CODE = "ic";

    //此常量的值不可更改
    private static final String CLIENT_ID = "client_id";


    /**
     * 修改登录密码
     *
     * @return
     */
    @ApiOperation(value = "修改登录密码接口", notes = "修改登录密码接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "密码修改信息", required = true, paramType = "body",
                    dataType = "UpdatePasswordRequest")
    })
    @RequestMapping(value = "/password/update", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<Boolean>> updatePassword(@RequestBody UpdatePasswordRequest request,
                                                            @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {

        Callable<HttpResult<Boolean>> callable = () -> {

            Long userId = null;
            try {
                userId = userDetails.getUserId();
            } catch (Exception ignored) {
            }

            if (userId == null)
                return HttpResult.failure("当前帐号未登录授权");

            TmtUser user = userService.findById(userId);

            if (!RegisterValidateHelper.validatePasswordEx(request.getNewPassword()))
                return HttpResult.failure("密码必须包含6-15位字母、数字或下划线，且同时包含大小写字母和数字");

            if (!userService.passwordMatch(user.getPassword(), request.getOldPassword()))
                return HttpResult.failure("原密码无效");

            userService.updatePassword(user.getId(), request.getNewPassword());

            return HttpResult.success("操作成功", true);
        };

        return new WebAsyncTask<>(callable);
    }

    /**
     * 获取推荐二维码
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "获取推荐二维码", notes = "返回的JSON数据中的data域即为二维码的内容，" +
            "其中ic参数为加密后的邀请码，注册应赋值给inviteCode字段；client_id参数为加密后的客户端ID")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "qrRequest", value = "获取推荐二维码", required = true, paramType = "body",
                    dataType = "QrCodeRequest")
    })
    @RequestMapping(value = "/qr", method = RequestMethod.POST)
    public WebAsyncTask<HttpResult<String>> getQRCode(HttpServletRequest request, @RequestBody QrCodeRequest qrRequest,
                                                      @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {

        Callable<HttpResult<String>> callable = () -> {
            ClientSystem clientSystem = clientSystemService.findByClientId(qrRequest.getClientId());
            if (clientSystem == null)
                return HttpResult.failure("客户端ID无效");

            Long userId = null;
            try {
                userId = userDetails.getUserId();
            } catch (Exception ignored) {
            }

            if (userId == null)
                return HttpResult.failure("当前帐号未登录授权");

            String enClientId = DesHelper.encrypt(clientSystem.getClientId());
            String enTmtUserId = DesHelper.encrypt(userId.toString());

            RequestMapping annotation = RegisterController.class.getAnnotation(RequestMapping.class);
            String url = request.getRequestURL().toString().replace(request.getRequestURI(),
                    request.getContextPath() + annotation.value()[0]);
            String regUrl = url + "?" + INTRODUCER_CODE + "=" + enTmtUserId + "&" + CLIENT_ID + "=" + enClientId;

            return HttpResult.success("操作成功", regUrl);
        };

        return new WebAsyncTask<>(callable);
    }

    /**
     * 获取锁粉列表
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "获取锁粉列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "获取锁粉列表", required = true, paramType = "body",
                    dataType = "InvitedUsersRequest")
    })
    @RequestMapping(value = "/invited", method = RequestMethod.POST)
    public WebAsyncTask getInvitedUserList(@RequestBody InvitedUsersRequest request,
                                           @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> queryInvitedUserList(request, userDetails));
    }

    /**
     * 提交用户实名认证资料
     *
     * @param authRequest
     * @return
     */
    @ApiOperation(value = "提交用户实名认证资料", notes = "提交用户实名认证资料")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authRequest", value = "用户实名认证请求", required = true, paramType = "body",
                    dataType = "RealNameAuthRequest")
    })
    @RequestMapping(value = "/realname", method = RequestMethod.POST)
    public WebAsyncTask realNameAuth(@RequestBody @ModelAttribute RealNameAuthRequest authRequest,
                                     @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> applyRealNameAuth(authRequest, userDetails));
    }

    /**
     * 用户实名认证申请结果查询接口
     *
     * @return
     */
    @ApiOperation(value = "用户实名认证申请结果查询接口", notes = "用户实名认证申请结果查询接口")
    @RequestMapping(value = "/realname/query", method = RequestMethod.POST)
    public WebAsyncTask queryRealNameAuth(@ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> queryRealNameAuthResult(userDetails));
    }

    /**
     * 用户实名认证申请记录删除接口
     *
     * @return
     */
    @ApiOperation(value = "用户实名认证申请记录删除接口", notes = "用户实名认证申请记录删除接口")
    @RequestMapping(value = "/realname/delete/{rlId}", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rlId",
                    value = "要删除的实名认证记录的ID",
                    required = true,
                    paramType = "path",
                    dataType = "long")
    })
    public WebAsyncTask deleteRealNameAuth(@PathVariable long rlId,
                                           @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> deleteRealNameAuthById(rlId, userDetails));
    }


    /**
     * 重新绑定手机号码
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "重新绑定手机号码", notes = "重新绑定手机号码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "绑定手机号码请求对象", required = true, paramType = "body",
                    dataType = "ChangeMobileRequest")
    })
    @RequestMapping(value = "/mobile/update", method = RequestMethod.POST)
    public WebAsyncTask changeMobile(@RequestBody ChangeMobileRequest request,
                                     @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> updateUserMobile(request, userDetails));
    }

    /**
     * 变更用户昵称
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "变更用户昵称", notes = "变更用户昵称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "昵称变更请求对象", required = true, paramType = "body",
                    dataType = "ChangeNickNameRequest")
    })
    @RequestMapping(value = "/nickname/update", method = RequestMethod.POST)
    public WebAsyncTask changeUserNickName(@RequestBody ChangeNickNameRequest request,
                                           @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> updateNickName(request, userDetails));
    }

    /**
     * 变更用户头像
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "变更用户头像", notes = "变更用户头像")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "头像变更请求对象", required = true, paramType = "body",
                    dataType = "ChangeAvatarRequest")
    })
    @RequestMapping(value = "/avatar/update", method = RequestMethod.POST)
    public WebAsyncTask changeUserAvatar(@RequestBody @ModelAttribute ChangeAvatarRequest request,
                                         @ApiIgnore @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return new WebAsyncTask<>(() -> updateAvatar(request, userDetails));
    }

}
